package com.fzhucc.modules.lesson.service.impl;

import com.fzhucc.exception.BadRequestException;
import com.fzhucc.modules.lesson.domain.Lesson;
import com.fzhucc.modules.lesson.domain.LessonLearnRecord;
import com.fzhucc.modules.lesson.domain.dto.LessonLearnRecordAddDto;
import com.fzhucc.modules.lesson.domain.dto.LessonLearnRecordDto;
import com.fzhucc.modules.lesson.domain.dto.LessonLearnRecordQueryCriteria;
import com.fzhucc.modules.lesson.repository.LessonLearnRecordRepository;
import com.fzhucc.modules.lesson.repository.LessonRepository;
import com.fzhucc.modules.lesson.service.LessonLearnRecordService;
import com.fzhucc.modules.lesson.service.mapstruct.LessonLearnRecordMapper;
import com.fzhucc.modules.system.service.UserService;
import com.fzhucc.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

/**
* @description 服务实现
* @author yyg
* @date 2022-12-08
**/
@Service
@RequiredArgsConstructor
public class LessonLearnRecordServiceImpl implements LessonLearnRecordService {

    private final LessonLearnRecordRepository lessonLearnRecordRepository;
    private final LessonLearnRecordMapper lessonLearnRecordMapper;

    private final LessonRepository lessonRepository;

    private final UserService userService;

    @Override
    public Map<String,Object> queryAll(LessonLearnRecordQueryCriteria criteria, Pageable pageable){
        Page<LessonLearnRecord> page = lessonLearnRecordRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        Page<LessonLearnRecordDto> res = page.map(lessonLearnRecordMapper::toDto);
        List<LessonLearnRecordDto> list = res.getContent();
        for (LessonLearnRecordDto lessonLearnRecordDto : list) {
            lessonLearnRecordDto.setUserDto(userService.findById(lessonLearnRecordDto.getUserId()));
            Optional<Lesson> result = lessonRepository.findById(lessonLearnRecordDto.getLessonId());
            if (result.isPresent()){
                lessonLearnRecordDto.setLesson(result.get());
            }
        }
        return PageUtil.toPage(res);
    }

    @Override
    public List<LessonLearnRecordDto> queryAll(LessonLearnRecordQueryCriteria criteria){
        return lessonLearnRecordMapper.toDto(lessonLearnRecordRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public LessonLearnRecordDto findById(Integer id) {
        LessonLearnRecord lessonLearnRecord = lessonLearnRecordRepository.findById(id).orElseGet(LessonLearnRecord::new);
        ValidationUtil.isNull(lessonLearnRecord.getId(),"LessonLearnRecord","id",id);
        return lessonLearnRecordMapper.toDto(lessonLearnRecord);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LessonLearnRecordDto create(LessonLearnRecordAddDto resources) {
        LessonLearnRecord lessonLearnRecord = new LessonLearnRecord();
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("用户ID未找到");
        }
        Optional<Lesson> res = lessonRepository.findById(resources.getLessonId());
        if (!res.isPresent()) {
            throw new BadRequestException("课程未找到");
        }
        lessonLearnRecord.setLabel("已学习");
        lessonLearnRecord.setLearnFinishTime(new Timestamp(new Date().getTime()));
        lessonLearnRecord.setUserId(userId);
        lessonLearnRecord.setLessonId(resources.getLessonId());
        return lessonLearnRecordMapper.toDto(lessonLearnRecordRepository.save(lessonLearnRecord));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(LessonLearnRecord resources) {
        LessonLearnRecord lessonLearnRecord = lessonLearnRecordRepository.findById(resources.getId()).orElseGet(LessonLearnRecord::new);
        ValidationUtil.isNull( lessonLearnRecord.getId(),"LessonLearnRecord","id",resources.getId());
        lessonLearnRecord.copy(resources);
        lessonLearnRecordRepository.save(lessonLearnRecord);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            lessonLearnRecordRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<LessonLearnRecordDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (LessonLearnRecordDto lessonLearnRecord : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("用户id", lessonLearnRecord.getUserId());
            map.put("课程id", lessonLearnRecord.getLessonId());
            map.put("学习情况", lessonLearnRecord.getLabel());
            map.put("学习完成时间", lessonLearnRecord.getLearnFinishTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public List<LessonLearnRecordDto> getLessonLearnRecordByMe() {
        List<LessonLearnRecordDto> result = new ArrayList<LessonLearnRecordDto>();
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("用户ID未找到");
        }
        List<LessonLearnRecord> list = lessonLearnRecordRepository.findByUserId(userId);
        for (LessonLearnRecord lessonLearnRecord : list) {
            LessonLearnRecordDto lessonLearnRecordDto = new LessonLearnRecordDto();
            lessonLearnRecordDto.setLessonId(lessonLearnRecord.getLessonId());
            lessonLearnRecordDto.setLearnFinishTime(lessonLearnRecord.getLearnFinishTime());
            lessonLearnRecordDto.setLabel(lessonLearnRecord.getLabel());
            lessonLearnRecordDto.setUserId(lessonLearnRecord.getUserId());
            Optional<Lesson> res = lessonRepository.findById(lessonLearnRecord.getLessonId());
            if (res.isPresent()) {
                lessonLearnRecordDto.setLesson(res.get());
            }
            result.add(lessonLearnRecordDto);
        }
        return result;
    }

    @Override
    public Map<String,Object> my(LessonLearnRecordQueryCriteria criteria, Pageable pageable){
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("未找到登录用户");
        }
        criteria.setUserId(userId);
        Page<LessonLearnRecord> page = lessonLearnRecordRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        Page<LessonLearnRecordDto> res = page.map(lessonLearnRecordMapper::toDto);
        List<LessonLearnRecordDto> list = res.getContent();
        for (LessonLearnRecordDto lessonLearnRecordDto : list) {
            lessonLearnRecordDto.setUserDto(userService.findById(lessonLearnRecordDto.getUserId()));
            Optional<Lesson> result = lessonRepository.findById(lessonLearnRecordDto.getLessonId());
            if (result.isPresent()){
                lessonLearnRecordDto.setLesson(result.get());
            }
        }
        return PageUtil.toPage(res);
    }
}